package com.bz.security;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import com.bz.common.JwtTokenUtil;
import com.bz.common.LogUtils;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil    jwtTokenUtil;

    @Autowired
    private AuthUserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException,
                                                                                                                       IOException {
        String requestId = UUID.randomUUID().toString();
        try {
            LogUtils.addMdc(requestId);

            String token = request.getHeader("token");// 获取header中的验证信息
            if (StringUtils.isEmpty(token)) {
                filterChain.doFilter(request, response);
                return;
            }
            if (!jwtTokenUtil.checkSign(token)) {
                filterChain.doFilter(request, response);
                return;
            }

            // 获取用户名
            String username = jwtTokenUtil.getUsername(token);
            if (StringUtils.isEmpty(username)) {
                filterChain.doFilter(request, response);
                return;
            }

            if (StringUtils.isNotEmpty(username) && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = userService.loadUserByToken(username);
                if (null == userDetails) {
                    filterChain.doFilter(request, response);
                    return;
                }
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null,
                    userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                // 设置为已登录
                SecurityContextHolder.getContext().setAuthentication(authentication);

                HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(request);
                requestWrapper.addHeader("username", username);
                filterChain.doFilter(requestWrapper, response);
                return;
            }
        } catch (Exception e) {
            LogUtils.error(log, e, "token解析失败");
        } finally {
            LogUtils.removeMdc();
        }

        try {
            LogUtils.addMdc(requestId);
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            LogUtils.error(log, e, "系统异常");
        } finally {
            LogUtils.removeMdc();
        }

    }
}
